<template>
  <div class="upload-container">
    <div
      v-if="video"
      class="video-container"
    >
      <div class="video-preview">
        <player
          :ratio="ratio"
          :src="video.url"
          :type="video.type"
        />
      </div>
      <div
        v-if="showUpload && percentage<100"
        class="video-upload__progress"
      >
        <el-progress
          :percentage="percentage"
          :color="percentageColor"
          :show-text="false"
        />
      </div>
      <div class="video-upload__actions">
        <template v-if="showUpload">
          <el-button
            icon="el-icon-upload"
            size="small"
            @click="submitUpload"
          >开始上传</el-button>
          <el-button
            size="small"
            @click="onRemove"
          >重新选取</el-button>
        </template>
        <el-button
          v-else
          icon="el-icon-delete"
          size="small"
          type="danger"
          @click="onDelete"
        >删除视频</el-button>
      </div>
    </div>
    <el-upload
      ref="videoUpload"
      :auto-upload="false"
      :show-file-list="false"
      :accept="acceptData"
      :action="action"
      :headers="uploadHeaders"
      :data="bindParams"
      :before-upload="beforeUpload"
      :http-request="onUpload"
      :on-success="handleSuccess"
      :on-progress="handleProgress"
      :on-preview="onPreview"
      :on-change="onChange"
      :drag="drag"
      :disabled="disabled"
      :class="uploaderClass"
    >
      <div
        slot="trigger"
        class="upload-trigger-container"
      >
        <div
          v-if="!video"
          class="upload-trigger__picker d-flex flex-column"
        >
          <div class="upload-trigger__picker-inner">
            <template v-if="loading">
              <i class="el-icon-loading" />
              <div class="upload-trigger__text">
                正在加载视频文件...
              </div>
            </template>
            <template v-else>
              <i class="el-icon-upload display3" />
              <div
                v-if="drag"
                class="upload-trigger__text"
              >
                将文件拖到此处，或<em>点击上传</em>
              </div>
              <div
                v-else
                class="upload-trigger__text"
              >
                选取要上传的视频文件
              </div>
            </template>
          </div>
        </div>
        <div
          v-else
          class="upload-trigger__checked"
        />
      </div>
      <div
        slot="tip"
        class="el-upload__tip"
      >
        <slot name="tips">
          <div v-if="tips">
            {{ tips }}
          </div>
        </slot>
      </div>
    </el-upload>
  </div>
</template>

<script>
import OSS from 'ali-oss'
import Player from '@/components/Player'
import { ossStsAuthent } from '@/api/attach'
import { generateUploadFileName } from '@/utils'
export default {
  name: 'SingleVideoUpload',
  components: {
    Player
  },
  props: {
    action: {
      type: String,
      default: `${process.env.VUE_APP_BASE_API}/attachs/upload`
    },
    fileList: {
      type: String,
      default: ''
    },
    drag: {
      type: Boolean,
      default: false
    },
    tips: {
      type: String,
      default: ''
    },
    ratio: {
      type: Number,
      default: 16 / 9
    },
    width: {
      type: [Number, String],
      default: ''
    },
    accept: {
      type: [Array, String],
      default: 'video/mp4'
    }
  },
  inject: ['uploadAction', 'uploadOptions'],
  data() {
    return {
      showUpload: false,
      percentage: 0,
      loading: false,
      uploaded: false,
      url: '',
      path: '',
      tempFile: null,
      disabled: false,
      uploadHeaders: {
        'Access-Control-Allow-Origin': '*'
      },
      authToken: {},
      bindParams: {}
    }
  },
  computed: {
    videoPath() {
      return this.fileList
    },
    video() {
      if (this.tempFile) {
        return this.tempFile
      }
      return this.fileList
        ? {
          url: this.fileList,
          type: 'video/mp4'
        }
        : null
    },
    uploaderClass() {
      var classes = ['video-uploader']
      if (this.ratio && !this.drag) {
        classes.push('uploader-ratio-box')
      }
      return classes
    },
    acceptData() {
      var accepts = this.accept
      if (Array.isArray) {
        if (Array.isArray(accepts)) {
          return accepts.join(', ')
        }
      } else if (accepts instanceof Array) {
        return accepts.join(', ')
      }
      return accepts
    }
  },
  created() {
    if (this.drag) {
      document.body.ondrop = function(event) {
        event.preventDefault()
        event.stopPropagation()
      }
    }
  },
  methods: {
    onPreview(f) {
      console.log(f)
    },
    submitUpload() {
      console.log('video submitUpload')
      this.$refs.videoUpload.submit()
    },
    onChange(file) {
      if (!this.tempFile) {
        this.loading = true
        // 此方法如果是大文件时会出现偶尔卡顿
        const reader = new FileReader()
        reader.readAsDataURL(file.raw)
        reader.onload = () => {
          this.tempFile = {
            url: reader.result,
            type: file.raw.type,
            name: file.name
          }
          this.loading = false
          this.percentage = 0
          this.showUpload = true
        }
      }
    },
    /**
     * @description [onUpload 覆盖默认的上传行为，实现自定义上传]
     * @author   shanshuizinong
     * @param    {object}   option [上传选项]
     * @return   {null}   [没有返回]
     */
    async onUpload(option) {
      console.log('onUpload', option)
      try {
        const vm = this
        vm.disabled = true
        // 获取OSS配置信息
        // const relativePath = ossData.relativePath
        const date = vm.$moment().format('YYYYMM/DD')
        const relativePath = 'attachments/sts/' + date + '/'
        const client = new OSS(vm.authToken)

        const file = option.file

        const point = file.name.lastIndexOf('.')
        const suffix = file.name.substr(point)
        const fileNames = generateUploadFileName(suffix)

        const uploadOptions = {
          progress: async p => {
            const e = {}
            e.percent = p * 100
            option.onProgress(e)
          },
          partSize: 500 * 1024,
          timeout: 60000
          // headers: {
          //   'Access-Control-Allow-Origin': '*'
          // }
        }
        // 分片上传文件
        const result = await client.multipartUpload(
          relativePath + fileNames,
          file,
          uploadOptions
        )
        console.log('upload', result)
        if (result.res.statusCode === 200) {
          // option.onSuccess(ret)
          vm.disabled = false
          return result
        } else {
          vm.disabled = false
          option.onError('上传失败')
        }
      } catch (error) {
        console.error(error)
        this.disabled = false
        option.onError('上传失败')
        this.$error(error.message)
      }
    },
    emitInput(val) {
      this.$emit('change', val)
    },
    onRemove() {
      this.tempFile = null
      this.emitInput('')
      console.log('this.video', this.video)
    },
    onDelete() {
      this.$confirm('此操作将删除商品视频, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.onRemove()
      })
    },
    handleSuccess(res) {
      console.log('handleSuccess res', res)
      this.showUpload = false
      this.emitInput(res.name)
    },
    handleProgress(d) {
      console.log('progress', d)
      this.percentage = d.percent
    },
    beforeUpload() {
      const _self = this
      return new Promise((resolve, reject) => {
        ossStsAuthent()
          .then(res => {
            const { data } = res
            _self.authToken = {
              // yourRegion填写Bucket所在地域。以华东1（杭州）为例，Region填写为oss-cn-hangzhou。
              region: 'oss-cn-hangzhou',
              bucket: data.bucket,
              // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
              accessKeyId: data.AccessKeyId,
              accessKeySecret: data.AccessKeySecret,
              // 填写Bucket名称，例如examplebucket。
              stsToken: data.SecurityToken
            }
            resolve(true)
          })
          .catch(err => {
            console.log(err)
            reject(false)
          })
      })
    },
    percentageColor(percentage) {
      if (percentage < 30) {
        return '#909399'
      } else if (percentage < 70) {
        return '#e6a23c'
      } else {
        return '#67c23a'
      }
    }
  }
}
</script>

<style lang="scss" scoped>
@import '~@/styles/mixin.scss';
:root {
  --ratio-percent: 56.25%;
  --ratio-width: 360px;
}
.upload-container {
  width: 100%;
  position: relative;
  line-height: initial;
  ::v-deep .el-upload {
    .el-upload-dragger {
      width: auto;
      height: auto;
    }
  }
  .upload-trigger {
    &__picker {
      position: relative;
      width: var(--ratio-width);
      &::after {
        content: '';
        padding-top: var(--ratio-percent);
        display: block;
      }
      &-inner {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 3px;
        color: #606266;
        img {
          width: 100%;
          height: 100%;
          object-fit: contain;
          border-radius: inherit;
        }
        i {
          margin: 0;
          &.el-icon-loading {
            color: #c0c4cc;
          }
        }
      }
      i + .upload-trigger__text {
        margin-top: 10px;
      }
    }
    &__checked {
      display: none;
    }
  }
  .el-upload {
    .el-upload-dragger {
      .upload-trigger__picker-inner {
        border: none;
      }
    }
  }
  .video-container {
    position: relative;
    width: var(--ratio-width);
    display: flex;
    flex-direction: column;
  }
  .video-upload {
    &__actions {
      margin-top: 10px;
    }
    &__progress {
      padding: 10px 0;
      & + .video-upload__actions {
        margin: 0;
      }
    }
  }
}
</style>
